using System.Collections.Generic;
using Unity.Collections;
using UnityEngine;
using UnityEngine.Assertions;
using UnityEngine.ParticleSystemJobs;
//需要开启cusumdata
/// <summary>
/// todo 目前不支持负数输入
/// </summary>
public class ParticleNumbers : MonoBehaviour
{
    [SerializeField] private ParticleSystem _ps;
    private UpdateParticlesNumJob job = new UpdateParticlesNumJob();

    void Start()
    {
        _ps = GetComponent<ParticleSystem>();
        Assert.IsNotNull(_ps, "No ParticleSystem Find");
        var customData = _ps.customData;
        customData.enabled = true;
        customData.SetMode(ParticleSystemCustomData.Custom1, UnityEngine.ParticleSystemCustomDataMode.Vector);
        //不支持动态大小,因为字间距更新问题
        var size1 = _ps.sizeBySpeed; size1.enabled = false;
        var size2 = _ps.sizeOverLifetime; size2.enabled = false;

    }

    private List<DamageDisplayData> _displayData = new List<DamageDisplayData>();
    //private List<int> hitNums = new List<int>();
    //private List<Vector3> hitPosition = new List<Vector3>();
    static readonly int[] sizeTable = { 9, 99, 999, 9999, 99999, 999999, 9999999,
                                      99999999, 999999999, int.MaxValue};

    // Requires positive x TODO 增加对负数的处理
    static int stringSize(uint x)
    {
        for (int i = 0; ; i++)
            if (x <= sizeTable[i])
                return i + 1;
    }
    //public void EmitteNums(int num , Vector3 pos)
    //{
    //    hitNums.Add(num);
    //    hitPosition.Add(pos);
    //}
    public void EmitNums(DamageDisplayData data)
    {
        _displayData.Add(data);
    }

    private void Update()
    {
        if (_displayData.Count > 0)
        {
            var customData = _ps.customData;
            customData.enabled = true;//未知原因编辑器中的数值会影响线程修改的值
            int emitCount = 0;
            foreach (var item in _displayData)
            {
                emitCount += stringSize((uint)item.Value);
            }
            //job.num = hitNums.ToNativeArray(Allocator.TempJob);
            //job.position = hitPosition.ToNativeArray(Allocator.TempJob);
            job.displayData = _displayData.ToNativeArray(Allocator.TempJob);
            job.viewRight = Camera.main.transform.right;
            _ps.Emit(emitCount);
            job.Schedule(_ps).Complete();
            job.displayData.Dispose();
            _displayData.Clear();
            //hitNums.Clear();
            //job.num.Dispose();
            //hitPosition.Clear();
            //job.position.Dispose();

            customData.enabled = false;
        }
    }
    //TODO 更新字间距
    //void OnParticleUpdateJobScheduled()

    //弃用
    /*struct UpdateParticlesJob : IJobParticleSystem
    //{
    //    [ReadOnly]
    //    public Vector3 viewRight;
    //    //[ReadOnly]
    //    //public NativeArray<int> num;
    //    //[ReadOnly]
    //    //public NativeArray<Vector3> position;
    //    [ReadOnly]
    //    public NativeArray<DamageDisplayData> displayData;

    //    static readonly Vector2[] flipIndex = {//0-9 -+
    //              new Vector2(0.625f, 0.0f) ,new Vector2(-0.025f   , 0), new Vector2(0.05f, 0.0f) , new Vector2(0.13f, 0) 
    //            , new Vector2(0.2f, 0) , new Vector2(0.27f, 0), new Vector2(0.345f, 0.0f) , new Vector2(0.415f, 0) 
    //            , new Vector2(0.48f , 0) , new Vector2(0.55f, 0),  new Vector2(0.7f, 0), new Vector2(0.75f, 0) };
    //    public void Execute(ParticleSystemJobData particles)
    //    {
    //        var startColors = particles.startColors;

    //        var positionsX = particles.positions.x;
    //        var positionsY = particles.positions.y;
    //        var positionsZ = particles.positions.z;

    //        var offsetX = particles.customData1.z; //数字图片偏移 id 4*4
    //        var offsetY = particles.customData1.w;
    //        int length = displayData.Length;
    //        int particleIdx = particles.count - 1;
    //        NativeArray<Vector2> strNum = new NativeArray<Vector2>(10, Allocator.Temp);
    //        for (int i = 0; i< length; i++)
    //        {
    //            var data = displayData[i];
    //            var unum = data.Value;
    //            var bit = 0;
    //            do
    //            {
    //                Vector2 n = flipIndex[unum % 10];//取unum的最后一位，并设置为str对应位，指示索引加1
    //                unum /= 10;//unum去掉最后一位
    //                strNum[bit] = n;


    //                bit++;
                    
    //            } while (unum!=0);//直至unum为0退出循环
    //            for (int j = 0; j < bit; j++)
    //            {
    //                //设置颜色
    //                switch (data.Type)
    //                {
    //                    case 0://普通伤害
    //                        startColors[particleIdx] = Color.yellow;
    //                        break;
    //                    default:
    //                        break;
    //                }
    //                //设置数值和位置
    //                offsetX[particleIdx] = strNum[j].x;
    //                offsetY[particleIdx] = strNum[j].y;
    //                var bitOffset = particles.sizes[particleIdx].x * j * -viewRight; //减法从做到右显示
    //                positionsX[particleIdx] = data.Position.x + bitOffset.x;
    //                positionsY[particleIdx] = data.Position.y + bitOffset.y;
    //                positionsZ[particleIdx] = data.Position.z + bitOffset.z;
    //                positionsX[particleIdx] += particles.sizes[particleIdx].x * bit * viewRight.x;
    //                particleIdx--;
    //            }

               
    //        }
    //    }
    //}*/
    struct UpdateParticlesNumJob : IJobParticleSystem
    {
        [ReadOnly]
        public Vector3 viewRight;
        //[ReadOnly]
        //public NativeArray<int> num;
        //[ReadOnly]
        //public NativeArray<Vector3> position;
        [ReadOnly]
        public NativeArray<DamageDisplayData> displayData;

        public void Execute(ParticleSystemJobData particles)
        {
            var startLifetime = particles.inverseStartLifetimes;
            var positionsX = particles.positions.x;
            var positionsY = particles.positions.y;
            var positionsZ = particles.positions.z;

            var textureIndex = particles.customData1.x; //2d texture 的序号

            int length = displayData.Length;
            int particleIdx = particles.count - 1;
            if (particleIdx < 0) return;
            NativeArray<byte> strNum = new NativeArray<byte>(10, Allocator.Temp);
            for (int i = 0; i < length; i++)
            {
                var data = displayData[i];
                uint unum = (uint)data.Value;//不支持负数
                var bit = 0;
                var sign = Mathf.Sign(data.Value);
                do
                {
                    uint n = unum % 10;//取unum的最后一位，并设置为str对应位，指示索引加1
                    unum /= 10;//unum去掉最后一位
                    strNum[bit] = (byte)n;


                    bit++;

                } while (unum != 0);//直至unum为0退出循环
                for (int j = 0; j < bit; j++)
                {
                    //设置数值图片
                    textureIndex[particleIdx] = strNum[j];
                    //最后一位放到最右边的顺序偏移
                    var bitOffset = particles.sizes[particleIdx].x * j * -viewRight;
                    //总体偏移长度 bit*sizeX
                    positionsX[particleIdx] = data.Position.x + particles.sizes[particleIdx].x * bit * viewRight.x + bitOffset.x;
                    positionsY[particleIdx] = data.Position.y + bitOffset.y;
                    positionsZ[particleIdx] = data.Position.z + bitOffset.z;
                    particleIdx--;
                    if (j < bit - 1)
                    {
                        startLifetime[particleIdx] = startLifetime[particleIdx + 1];
                    }

                }


            }
        }
    }
}
